package com.learn.security.web.filters;

import com.learn.security.common.VerifyConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.web.WebAttributes;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import org.thymeleaf.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @auther liuhw
 * @date 2020/3/21 22:13
 * @description:
 * @since 1.0
 **/
@Slf4j
public class VerifyFilter extends OncePerRequestFilter {
    private final static PathMatcher matcher = new AntPathMatcher();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (isProtectedUrl(request) && !validateVerify(request, request.getParameter("verifyCode"))) {
            request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, new DisabledException("验证码输入错误"));
            request.getRequestDispatcher("/login/error").forward(request, response);
        } else {
            filterChain.doFilter(request, response);
        }
    }

    /**
     * 判断输入的验证码是否合法
     * @param request
     * @param code
     * @return
     */
    private boolean validateVerify(HttpServletRequest request, String code) {
        // 获取session中的验证码
        String validateCode = String.valueOf(request.getSession().getAttribute(VerifyConstant.VERIFY_CODE_NAME));
        return StringUtils.equalsIgnoreCase(validateCode, code);
    }

    /**
     * 判断是否是 /login 的 POST 请求
     * @param request
     * @return
     */
    private boolean isProtectedUrl(HttpServletRequest request) {
        return matcher.match("/login", request.getServletPath()) && HttpMethod.POST.matches(request.getMethod());
    }
}
